namespace Domotica.Windows.Input
{
    using System;
    using System.Windows;
    using System.Windows.Input;
    using Domotica.Gazing;
    using Domotica.Windows.Controls;

    public class GazeDevice
    {
        public GazeDevice()
        {
            gaze = new Gaze();
            gaze.FaceMove += new Domotica.Gazing.GazeEventHandler(OnFaceMove);
            Application.Current.Exit += new ExitEventHandler(AppplicationExit);

            //gaze.GazeClicked += new GazeClickEventHandler(OnGazeClick);
            //gaze.GazeClickedElapsed += new GazeClickElapsedEventHandler(OnGazeClickElapsedChanged);
            //gaze.ImageProcessed+=new ImageProcessedEventHandler(OnImageProcessed);
        }

        private void AppplicationExit(object sender, ExitEventArgs e)
        {
            gaze.StopCapture();
        }

        private Gaze gaze;
        private static GazeDevice _Current;

        public static GazeDevice Current
        {
            get
            {
                if (_Current == null)
                {
                    _Current = new GazeDevice();
                }
                return _Current;
            }
        }

        public IInputElement Target(Point gazePosition)
        {
            foreach (GazeWindow e in Extenders)
            {
                IInputElement ie = e.InputHitTest(e.PointFromScreen(gazePosition));
                if (ie != null)
                {
                    return ie;
                }
            }
            return null;
        }

        private IGazeable GazeAbleTarget(Point gazePosition)
        {
            FrameworkElement ie = Target(gazePosition) as FrameworkElement;
            while (ie != null && !(ie is IGazeable))
            {
                if (ie.Parent != null)
                {
                    ie = ie.Parent as FrameworkElement;
                }
                else
                {
                    ie = ie.TemplatedParent as FrameworkElement;
               }
            }
            return ie as IGazeable;
        }

        #region Events
        
        private void OnFaceMove(object sender, Domotica.Gazing.GazeEventArgs e)
        {
            IGazeable gazeable = GazeAbleTarget(e.Position);
            if (gazeable == null)
            {
                return;
            }
            gazeable.OnFaceMove(e);
        }

        public event ImageProcessedEventHandler ImageProcessed;

        private void OnImageProcessed(object sender, ImageProcessedEventArgs e)
        {
            if (ImageProcessed != null)
            {
                ImageProcessed(this, e);
            }
        }

        public event GazeClickEventHandler GazeClicked;

        private void OnGazeClick(object sender, GazeClickEventArgs e)
        {
            if (GazeClicked != null)
            {
                GazeClicked(this, e);
            }
        }

        public event GazeClickElapsedEventHandler GazeClickedElapsed;

        private void OnGazeClickElapsedChanged(object sender, GazeClickElapsedEventArgs e)
        {
            if (GazeClickedElapsed != null)
            {
                GazeClickedElapsed(this, e);
            }
        }

        #endregion

        #region methods

        private GazingWindowExtenderList Extenders = new GazingWindowExtenderList(); 

        internal void Register(GazeWindow extender)
        {
            if (!Extenders.Contains(extender))
            {
                Extenders.Add(extender);
            }
        }

        internal void UnRegister(GazeWindow extender)
        {
            if (Extenders.Contains(extender))
            {
                Extenders.Remove(extender);
            }
        }


        #endregion

        public void Stop()
        {
            gaze.StopCapture();
        }

    }
}

